package com.fankui.crowd.mvc.config;

import com.fankui.crowd.constant.CrowdConstant;
import com.fankui.crowd.exception.LoginAcctAlreadyInUserException;
import com.fankui.crowd.exception.LoginAcctAlreadyInUserForUpdateException;
import com.fankui.crowd.exception.LoginFailedException;
import com.fankui.crowd.exception.RoleAlreadyInException;
import com.fankui.crowd.util.CrowdUtil;
import com.fankui.crowd.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * ClassName CrowdExceptionResolver
 * Description TODO
 * Date 2023/7/28 17:03
 *
 * @Author 范奎
 * @Since JDK 11
 */
// @ControllerAdvice: 表示当前类是一个基于注解的异常处理器类
@ControllerAdvice
public class CrowdExceptionResolver {

    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveLoginFailedException(LoginFailedException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-login";
        return commonResolve(viewName, e, request, response);
    }

    @ExceptionHandler(value = LoginAcctAlreadyInUserException.class)
    public ModelAndView resolveLoginAcctAlreadyInUserException(LoginAcctAlreadyInUserException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-add";
        return commonResolve(viewName, e, request, response);
    }

    @ExceptionHandler(value = Exception.class)
    public ModelAndView resolveException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName, e, request, response);
    }

    @ExceptionHandler(value = RoleAlreadyInException.class)
    public ModelAndView resolveRoleAlreadyInException(RoleAlreadyInException e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName, e, request, response);
    }

    private ModelAndView commonResolve(String viewName, Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1 判断当前请求类型是不是Ajax请求
        boolean judgeRequest = CrowdUtil.judgeRequestType(request);
        // 2 如果是Ajax请求
        if (judgeRequest) {
            // 2.1.1 创建ResuleEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(e.getMessage());
            // 2.1.2 创建Gson对象
            Gson gson = new Gson();
            // 2.1.3 将ResuleEntity对象转换为JSON字符串
            String json = gson.toJson(resultEntity);
            // 2.1.4 将JSON字符串作为响应体返回给浏览器
            response.getWriter().write(json);
            // 2.1.5 由于上面已经通过原生的response对象返回了响应，所以不再提供ModelAndView对象
            return null;
        } else {
            // 2.2.1 如果不是Ajax请求则创建ModelAndView对象
            ModelAndView modelAndView = new ModelAndView();
            // 2.2.2 将Exception对象存入模型
            modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, e);
            // 2.2.3 设置对应的试图名称
            modelAndView.setViewName(viewName);
            // 2.2.4 返回modelAndView对象
            return modelAndView;
        }
    }
}
